package com.agritech.task;

import com.agritech.machine.AgriculturalMachine;
import com.agritech.path.PathPlan;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务调度系统
 * 负责任务的创建、分配、执行和监控
 */
public class TaskScheduler {
    private final List<Task> taskQueue; // 任务队列
    private final Map<String, Task> activeTasks; // 活动任务列表 (taskId -> Task)
    private final List<AgriculturalMachine> availableMachines; // 可用农机列表
    private int nextTaskId = 1;

    public TaskScheduler(List<AgriculturalMachine> initialMachines) {
        this.taskQueue = new ArrayList<>();
        this.activeTasks = new HashMap<>();
        this.availableMachines = new ArrayList<>(initialMachines);
        System.out.println("任务调度系统已初始化，可用农机数量: " + availableMachines.size());
    }

    /**
     * 创建新任务并添加到队列
     * @param taskName 任务名称
     * @param taskDescription 任务描述
     * @param estimatedDuration 预计时长（小时）
     * @return 创建的任务对象
     */
    public Task createTask(String taskName, String taskDescription, double estimatedDuration) {
        String taskId = "TASK-" + String.format("%04d", nextTaskId++);
        Task newTask = new Task(taskId, taskName, taskDescription, estimatedDuration);
        taskQueue.add(newTask);
        System.out.println("新任务已创建: " + newTask.getTaskName() + " (ID: " + newTask.getTaskId() + ")，已加入待处理队列");
        return newTask;
    }

    /**
     * 分配任务给指定的农机
     * @param task 要分配的任务
     * @param machine 指定的农机
     * @param pathPlan 任务的路径规划
     */
    public void assignTask(Task task, AgriculturalMachine machine, PathPlan pathPlan) {
        if (task == null || machine == null) {
            System.out.println("任务分配失败: 任务或农机对象为空");
            return;
        }
        if (!availableMachines.contains(machine)) {
            System.out.println("任务分配失败: 农机 " + machine.getId() + " 不可用或不存在");
            return;
        }
        if (task.getStatus() != Task.TaskStatus.PENDING) {
            System.out.println("任务分配失败: 任务 '" + task.getTaskName() + "' 状态不为待处理");
            return;
        }

        task.assignToMachine(machine, pathPlan);
        availableMachines.remove(machine); // 农机变为占用状态
        activeTasks.put(task.getTaskId(), task);
        taskQueue.remove(task);
        System.out.println("农机 " + machine.getId() + " 已被分配任务，当前不可用");
    }

    /**
     * 自动分配队列中的任务给可用农机
     * (简单实现：分配给第一个可用的同类型农机或任意农机)
     */
    public void autoAssignTasks() {
        if (taskQueue.isEmpty()) {
            System.out.println("任务队列为空，无需自动分配");
            return;
        }
        if (availableMachines.isEmpty()) {
            System.out.println("无可用农机，无法自动分配任务");
            return;
        }

        System.out.println("开始自动分配任务...");
        List<Task> assignedTasksThisRound = new ArrayList<>();

        for (Task task : new ArrayList<>(taskQueue)) { // 遍历副本以允许在循环中修改原始列表
            AgriculturalMachine bestFitMachine = findBestFitMachine(task);
            if (bestFitMachine != null) {
                // 假设自动分配时没有预设路径规划，或路径规划在任务执行时动态生成
                assignTask(task, bestFitMachine, null); 
                assignedTasksThisRound.add(task);
                if (availableMachines.isEmpty()) {
                    System.out.println("所有农机均已分配任务");
                    break;
                }
            }
        }
        if (assignedTasksThisRound.isEmpty()){
            System.out.println("本轮未成功分配任何任务，可能无匹配农机或农机均忙碌");
        } else {
            System.out.println("本轮自动分配完成，共分配 " + assignedTasksThisRound.size() + " 个任务");
        }
    }

    /**
     * 查找最适合任务的农机 (简单匹配逻辑)
     * @param task 任务
     * @return 合适的农机，或null
     */
    private AgriculturalMachine findBestFitMachine(Task task) {
        // 优先匹配同类型农机，这里简化为任意可用农机
        // 实际应用中可以根据任务类型、农机能力、位置等进行匹配
        if (!availableMachines.isEmpty()) {
            return availableMachines.get(0); // 返回第一个可用的农机
        }
        return null;
    }

    /**
     * 启动指定ID的任务
     * @param taskId 任务ID
     */
    public void startTask(String taskId) {
        Task task = activeTasks.get(taskId);
        if (task != null) {
            if (task.getAssignedMachine().isRunning()) { // 检查农机是否已启动
                 task.startTask();
            } else {
                System.out.println("农机 " + task.getAssignedMachine().getId() + " 未启动，请先启动农机再开始任务");
            }
        } else {
            System.out.println("无法启动任务: 未找到ID为 '" + taskId + "' 的活动任务");
        }
    }

    /**
     * 完成指定ID的任务
     * @param taskId 任务ID
     */
    public void completeTask(String taskId) {
        Task task = activeTasks.get(taskId);
        if (task != null) {
            task.completeTask();
            if (task.getStatus() == Task.TaskStatus.COMPLETED || task.getStatus() == Task.TaskStatus.FAILED || task.getStatus() == Task.TaskStatus.CANCELLED) {
                AgriculturalMachine machine = task.getAssignedMachine();
                if (machine != null) {
                    availableMachines.add(machine); // 释放农机
                    System.out.println("农机 " + machine.getId() + " 已完成任务，恢复可用状态");
                }
                activeTasks.remove(taskId);
            }
        } else {
            System.out.println("无法完成任务: 未找到ID为 '" + taskId + "' 的活动任务");
        }
    }
    
    /**
     * 取消指定ID的任务
     * @param taskId 任务ID
     */
    public void cancelTask(String taskId) {
        Task task = activeTasks.get(taskId);
        if (task != null) {
            task.cancelTask();
             AgriculturalMachine machine = task.getAssignedMachine();
            if (machine != null) {
                availableMachines.add(machine); // 释放农机
                System.out.println("农机 " + machine.getId() + " 因任务取消，恢复可用状态");
            }
            activeTasks.remove(taskId);
        } else {
            // 检查是否在任务队列中
            Task queuedTask = taskQueue.stream().filter(t -> t.getTaskId().equals(taskId)).findFirst().orElse(null);
            if (queuedTask != null) {
                queuedTask.cancelTask();
                taskQueue.remove(queuedTask);
            } else {
                 System.out.println("无法取消任务: 未找到ID为 '" + taskId + "' 的任务");
            }
        }
    }

    /**
     * 打印所有任务状态
     */
    public void printAllTaskStatuses() {
        System.out.println("\n--- 任务状态概览 ---");
        System.out.println("待处理任务队列 (" + taskQueue.size() + " 个):");
        if (taskQueue.isEmpty()) {
            System.out.println("  无待处理任务");
        } else {
            taskQueue.forEach(task -> System.out.println("  - " + task.getTaskName() + " (ID: " + task.getTaskId() + ", 状态: " + task.getStatus().getDescription() + ")"));
        }

        System.out.println("\n活动任务列表 (" + activeTasks.size() + " 个):");
        if (activeTasks.isEmpty()) {
            System.out.println("  无活动任务");
        } else {
            activeTasks.values().forEach(task -> 
                System.out.println("  - " + task.getTaskName() + " (ID: " + task.getTaskId() + 
                                   ", 农机: " + (task.getAssignedMachine() != null ? task.getAssignedMachine().getId() : "未分配") + 
                                   ", 状态: " + task.getStatus().getDescription() + ")")
            );
        }
        System.out.println("--------------------\n");
    }
    
    /**
     * 获取指定ID的任务详情
     * @param taskId 任务ID
     */
    public void printTaskDetails(String taskId) {
        Task task = activeTasks.get(taskId);
        if (task != null) {
            task.printTaskDetails();
        } else {
            task = taskQueue.stream().filter(t -> t.getTaskId().equals(taskId)).findFirst().orElse(null);
            if (task != null) {
                task.printTaskDetails();
            } else {
                 System.out.println("未找到ID为 '" + taskId + "' 的任务");
            }
        }
    }

    /**
     * 获取可用农机列表
     * @return 可用农机列表
     */
    public List<AgriculturalMachine> getAvailableMachines() {
        return new ArrayList<>(availableMachines);
    }
    
    /**
     * 获取所有农机列表（包括已分配任务的）
     * @return 所有农机列表
     */
    public List<AgriculturalMachine> getAllMachines() {
        List<AgriculturalMachine> all = new ArrayList<>(availableMachines);
        activeTasks.values().forEach(task -> {
            if (task.getAssignedMachine() != null && !all.contains(task.getAssignedMachine())) {
                all.add(task.getAssignedMachine());
            }
        });
        return all;
    }

    /**
     * 获取任务队列中的任务
     * @return 任务队列
     */
    public List<Task> getTaskQueue() {
        return new ArrayList<>(taskQueue);
    }

    /**
     * 获取活动任务列表
     * @return 活动任务Map
     */
    public Map<String, Task> getActiveTasks() {
        return new HashMap<>(activeTasks);
    }
}